package com.pt25.service.sys.domain.admin.service.impl;

import com.pt25.base.dep.redis.RedisService;
import com.pt25.base.exception.BizException;
import com.pt25.base.model.common.constants.RedisConstant;
import com.pt25.service.sys.domain.admin.ddo.AdminPermission;
import com.pt25.service.sys.domain.admin.factory.AdminFactory;
import com.pt25.service.sys.domain.admin.service.AdminPermissionService;
import com.pt25.service.sys.repository.mysql.persistence.AdminPermissionRepo;
import com.pt25.service.sys.repository.mysql.persistence.AdminRolePermissionRepo;
import com.pt25.service.sys.repository.mysql.po.AdminPermissionPo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AdminPermissionServiceImpl implements AdminPermissionService {
    @Resource
    private RedisService redisService;

    @Resource
    private AdminPermissionRepo adminPermissionRepo;

    @Resource
    private AdminRolePermissionRepo adminRolePermissionRepo;

    @Resource
    private AdminFactory adminFactory;

    @Override
    public void addAdminPermission(AdminPermission adminPermission) {
        AdminPermissionPo adminPermissionPO = adminFactory.adminPermission2AdminPermissionPO(adminPermission);
        if (null == adminPermissionRepo.getAdminPermissionByPermissionOrTitle(adminPermissionPO)) {
            adminPermissionPO.setId(redisService.genAutoIncrID(RedisConstant.CLUSTER1, AdminPermissionPo.key));
            adminPermissionPO.setLevel(getPermissionLevel(adminPermission.getParentId()));
            adminPermissionRepo.save(adminPermissionPO);
            return;
        }
        throw new BizException("权限:" + adminPermission.getPermission() + "或权限名称:" + adminPermission.getTitle() + "已经存在！");
    }

    @Transactional
    @Override
    public void delAdminPermission(Long id) {
        //获取所有需要删除的权限的id
        Set<Long> needDeletePermissionIds = new HashSet<>();
        needDeletePermissionIds.add(id);
        getNeedDeleteAdminPermissionIds(id, needDeletePermissionIds);
        //删除角色权限
        adminRolePermissionRepo.delRolePermissionByPermissionIds(needDeletePermissionIds);
        //删除所有权限
        adminPermissionRepo.removePermissionByPermissionIds(needDeletePermissionIds);
    }


    @Override
    public void updateAdminPermission(AdminPermission adminPermission) {
        AdminPermissionPo adminPermissionPO = adminFactory.adminPermission2AdminPermissionPO(adminPermission);
        AdminPermission adminPermissionByPermissionOrTitle = adminPermissionRepo.getAdminPermissionByPermissionOrTitle(adminPermissionPO);
        if (adminPermissionByPermissionOrTitle == null || adminPermissionByPermissionOrTitle.getId().equals(adminPermission.getId())) {
            adminPermissionRepo.updateById(adminPermissionPO);
            return;
        }
        throw new BizException("权限:" + adminPermission.getPermission() + "或权限名称:" + adminPermission.getTitle() + "已经存在！");
    }

    @Override
    public AdminPermission getAdminPermission(Long id) {
        return adminPermissionRepo.getAdminPermission(id);
    }

    @Override
    public Set<String> getPermissionsByRoleIds(Set<Long> roleIds) {
        List<AdminPermission> adminPermissions = adminPermissionRepo.getAdminPermissionsByIds(adminRolePermissionRepo.getPermissionIdsByRoleIds(roleIds));
        return adminPermissions.stream().map(AdminPermission::getPermission).collect(Collectors.toSet());
    }

    @Override
    public List<AdminPermission> listAdminPermission() {
        return adminPermissionRepo.listAdminPermission();
    }

    private Integer getPermissionLevel(Long parentId) {
        AdminPermission adminPermission = adminPermissionRepo.getAdminPermission(parentId);
        if (null != adminPermission) {
            return adminPermission.getLevel() + 1;
        }
        return 0;
    }

    private void getNeedDeleteAdminPermissionIds(Long id, Set<Long> needDeleteAdminPermissionIds) {
        List<AdminPermission> childAdminPermissions = adminPermissionRepo.listAdminPermissionByParentId(id);
        needDeleteAdminPermissionIds.addAll(childAdminPermissions.stream().map(AdminPermission::getId).collect(Collectors.toSet()));
        for (AdminPermission adminPermission : childAdminPermissions) {
            if (adminPermission.getLevel() != 2) {
                getNeedDeleteAdminPermissionIds(adminPermission.getId(), needDeleteAdminPermissionIds);
            }
        }
    }
}
